﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StableDiffusionTools.Controls
{
    public class ColorPreview : Control
    {
        private int currentCheckerSize = -1;
        private Bitmap backgroundCheckers = null;
        private ImageAttributes tileAttributes;

        private Color color = Color.Black;
        public Color Color {
            get
            {
                return color;
            }
            set
            {
                if(value != color)
                {
                    color = value;
                    Invalidate();
                }
            }
        }

        private int checkerSize = 16;
        public int CheckerSize
        {
            get => checkerSize;
            set
            {
                if(checkerSize != value)
                {
                    checkerSize = value;
                    Invalidate();
                }
            }
        }

        private bool useAlpha = true;
        public bool UseAlpha
        {
            get => useAlpha;
            set
            {
                if(useAlpha != value)
                {
                    useAlpha = value;
                    Invalidate();
                }
            }
        }

        public ColorPreview()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true);
            tileAttributes = new ImageAttributes();
            tileAttributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.Tile);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            int totalSize = checkerSize * 2;
            if (useAlpha && (backgroundCheckers == null || currentCheckerSize != checkerSize))
            {
                DestroyCheckersBitmap();
                currentCheckerSize = checkerSize;
                backgroundCheckers = RenderCheckers(totalSize);
            }

            Rectangle clip = e.ClipRectangle;

            if(useAlpha)
                using (TextureBrush tileBrush = new TextureBrush(backgroundCheckers, new Rectangle(0, 0, totalSize, totalSize), tileAttributes))
                    e.Graphics.FillRectangle(tileBrush, 0, 0, Width, Height);

            using (var backBrush = new SolidBrush(useAlpha ? Color : Color.FromArgb(255, Color)))
                e.Graphics.FillRectangle(backBrush, clip);

            using (var borderPen = new Pen(Color.Black))
                e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, Width - 1, Height - 1));
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //base.OnPaintBackground(pevent);
        }

        private void DestroyCheckersBitmap()
        {
            if (backgroundCheckers != null)
            {
                backgroundCheckers.Dispose();
                backgroundCheckers = null;
            }
        }

        private static Bitmap RenderCheckers(int totalSize)
        {
            int halfSize = totalSize / 2;
            Bitmap result = new Bitmap(totalSize, totalSize, PixelFormat.Format32bppPArgb);
            using (var g = Graphics.FromImage(result))
            {
                using (var darkBrush = new SolidBrush(Color.DarkGray))
                using (var lightBrush = new SolidBrush(Color.LightGray))
                {
                    g.FillRectangle(darkBrush, new Rectangle(0, 0, totalSize, totalSize));
                    g.FillRectangle(lightBrush, new Rectangle(halfSize, 0, halfSize, halfSize));
                    g.FillRectangle(lightBrush, new Rectangle(0, halfSize, halfSize, halfSize));
                }
            }
            return result;
        }
    }
}
